---
title: "Trigger AWS Lambdas from database changes"
sidebarTitle: "AWS Lambda (via webhook)"
description: "Build serverless event-driven applications by streaming Postgres changes to AWS Lambda."
---

[AWS Lambda](https://aws.amazon.com/lambda/) is a serverless compute service that lets you run code without provisioning or managing servers. It automatically scales your applications in response to incoming requests.

Often, you want to trigger an AWS Lambda function when a database row changes. For example, you may want to trigger a function as a side-effect of a database change, or fan out work to multiple services.

<Frame>
  <img src="/images/guides/lambda/send-with-sequin.svg" alt="AWS Lambda Function" />
</Frame>


In this guide, you will learn how to setup a Sequin webhook sink to trigger an AWS Lambda function when a database row changes.

## Prerequisites

You are about to create a simple AWS Lambda function that logs a message to the console. You'll trigger this function by setting up a Sequin webhook sink that sends a HTTP POST request to the function's URL with the payload of the database row that changed.

You'll need the following:

- An [AWS account](https://aws.amazon.com/)
- Sequin [installed locally](/quickstart/webhooks)
- A [database](/connect-postgres) connected to Sequin

## Create a Lambda function

Start by creating a new AWS Lambda function that takes in a Sequin change event as a payload and logs the payload to the console.

<Steps titleSize="h3">
  <Step title="Create a new Lambda function">
      1. Open the AWS Lambda console and click "Create function".
      2. Choose "Author from scratch".
      3. Give your function a name (e.g., "newUserHandler").
      4. Select a runtime (e.g., "Node.js 20.x") and which ever architecture you want to support (e.g., "arm64").
      5. Click "Create function":

      <Frame>
        <img src="/images/guides/lambda/setup-lambda.png" alt="Setup lambda function" />
      </Frame>
  </Step>
  <Step title="Add function code">
      Replace the default code in the Lambda function. Here's an example:

      ```javascript index.mjs
      export const handler = async (event) => {
        // Verify the Sequin webhook secret
        const authHeader = event.headers.authorization;
        if (!authHeader || authHeader !== `Bearer ${process.env.SEQUIN_WEBHOOK_SECRET}`) {
          return {
            statusCode: 401,
            body: JSON.stringify('Unauthorized'),
          };
        }

        try {
          const payload = JSON.parse(event.body);
          const { record } = payload;

          if (record && record.name) {
            console.log(`Hello ${record.name}`);
          } else {
            console.log('No name found in the payload.');
          }

          return {
            statusCode: 200,
            body: JSON.stringify('Success'),
          };
        } catch (error) {
          console.error('Error processing request:', error);
          return {
            statusCode: 500,
            body: JSON.stringify('Internal Server Error'),
          };
        }
      };
      ```

      This function first checks the authorization header to make sure the request is coming from Sequin. Then it processes the [payload](/reference/sinks/webhooks#request-format) and logs the name from the payload to the console.

      Click "Deploy" to save the function.
  </Step>
  <Step title="Add the SEQUIN_WEBHOOK_SECRET environment variable">
      1. In the Lambda function "Configuration" tab, scroll down to the "Environment variables" section.
      2. Click "Edit" and then "Add environment variable".
      3. Set the key as `SEQUIN_WEBHOOK_SECRET` and the value to [a secure secret of your choice](/reference/sinks/webhooks#authentication).
      4. Click "Save".

      You will need to use this secret value in the Sequin dashboard when you create the push consumer.
  </Step>
  <Step title="Create a Lambda Function URL">
      To make your Lambda function accessible via HTTP, you need to create a Function URL:

      1. Go to your Lambda function in the AWS Console.
      2. In the "Configuration" tab, click on "Function URL" in the left sidebar.
      3. Click "Create function URL".
      4. For "Auth type", select "NONE".
      5. Under "Configure cross-origin resource sharing (CORS)", check "Configure CORS".
      6. In the "Allowed origins" field, enter "*" (without quotes) to allow all origins for now. You can restrict this later.
      7. Click "Save".

      After saving, you'll see a Function URL. This is the URL you'll use to configure your Sequin consumer in the next section.
  </Step>
</Steps>

<Check>
You've successfully created an AWS Lambda function that logs a message to the console when Sequin sends a HTTP POST request to the function's URL.
</Check>

## Create a webhook sink

Create a webhook sink that captures changes to your database and sends a HTTP POST request to the Lambda function's URL:

<Steps titleSize="h3">
    <Step title="Create a new sink">
        Navigate to the "Sinks" tab, click the "Create Sink" button, and select "Webhook Sink".
    </Step>

    <Step title="Select source tables">
        Select the schemas and tables you want to capture changes from (i.e `public.users` or `public`).
    </Step>

    <Step title="Add filters (optional)">
        Add [filters](/reference/filters) to the sink to control which database changes are sent to your webhook endpoint.
    </Step>

    <Step title="Configure backfill">
        You can optionally indicate if you want your webhook endpoint to receive a [backfill](reference/backfills) of all or a portion of the table's existing data. For now, leave "Backfill" toggled off.
    </Step>

    <Step title="Configure message grouping">
        Under "Message grouping", leave the default option selected to ensure events for the same row are sent to your webhook endpoint in order.
    </Step>

   <Step title="Configure sink settings">
        Under "Webhook Sink configuration" leave the defaults:

        - Leave the default value of `30000 ms` for "Request timeout" as this is more than enough time for your Lambda function to process the request
        - Leave the default value of `1` for "Batch size" so each change is processed individually.
    </Step>

    <Step title="Configure HTTP endpoint">
        Under "HTTP Endpoint", enter the Lambda Function URL you obtained earlier. Then click to "Add Encrypted Header" with the key `Authorization` and the value `Bearer SEQUIN_WEBHOOK_SECRET`, using the secret value you set in your Lambda function's environment variables.
    </Step>

    <Step title="Name and create sink">
        Give your sink a name (i.e. `users_webhook_sink`) and click "Create Webhook Sink".
    </Step>
</Steps>

<Check>
    Your Sequin consumer is now created and ready to send events to your Lambda function.
</Check>

## Test end-to-end
<Steps titleSize="h3">
    <Step title="Add a row to your table">

    Insert a row into your table. For example:

    ```sql
    insert into
    users (name)
    values
      (
        'John Doe'
      );
    ```
    </Step>
    <Step title="Trace the change in the Sequin dashboard">
    In the Sequin console, open the **Messages** tab on your webhook sink and confirm that a message was delivered:

    <Frame>
      <img src="/images/guides/lambda/observe-message.png" alt="Trace message" />
    </Frame>
    </Step>

    <Step title="Confirm the event was received by your Lambda function">
    1. Open the AWS Lambda console and navigate to your function.
    2. Click on the "Monitor" tab and then "View CloudWatch logs".
    3. In the most recent log stream, you should see a log entry: `Hello John Doe`:

    <Frame>
      <img src="/images/guides/lambda/log.png" alt="Confirm message" />
    </Frame>
    </Step>
</Steps>

<Check>
You've successfully triggered an AWS Lambda function from a database change!
</Check>

## Next steps

Modify this example to suit your needs:

- If you need to run long-running jobs, consider using [AWS Step Functions](https://aws.amazon.com/step-functions/) in tandem with Lambda functions.
- Tune your [webhook sink configuration](/reference/sinks/webhooks) to suit your volume of work.
- Implement additional security measures, such as [API Gateway request validation](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-method-request-validation.html).